#include <SDL/SDL.h>
#include "calc.h"
#define GUI_SDL
#include "gui_sdl_emu.h"

// Variables, variables, variables...
SDL_Surface* screen = NULL;
SDL_Surface* lcdsurface = NULL;

// Functions for SDL
/*Uint32 SDL_MapRGB
(const SDL_PixelFormat * const format,
 const Uint8 r, const Uint8 g, const Uint8 b)
{
        if ( format->palette == NULL ) {
                return (r >> format->Rloss) << format->Rshift
                       | (g >> format->Gloss) << format->Gshift
                       | (b >> format->Bloss) << format->Bshift
                       | format->Amask;
        } else {
                return SDL_FindColor(format->palette, r, g, b);
        }
}*/
typedef unsigned char Uint8;
//typedef long int Sint32;
void DrawPixel(SDL_Surface *screen, Uint8 R, Uint8 G, Uint8 B, Sint32 x, Sint32 y)
{
    Uint32 color = SDL_MapRGB(screen->format, R, G, B);

    if ( SDL_MUSTLOCK(screen) ) {
        if ( SDL_LockSurface(screen) < 0 ) {
            return;
        }
    }
    switch (screen->format->BytesPerPixel) {
        case 1: { /* Assuming 8-bpp */
            Uint8 *bufp;

            bufp = (Uint8 *)screen->pixels + y*screen->pitch + x;
            *bufp = color;
        }
        break;

        case 2: { /* Probably 15-bpp or 16-bpp */
            Uint16 *bufp;

            bufp = (Uint16 *)screen->pixels + y*screen->pitch/2 + x;
            *bufp = color;
        }
        break;

        case 3: { /* Slow 24-bpp mode, usually not used */
            Uint8 *bufp;

            bufp = (Uint8 *)screen->pixels + y*screen->pitch + x;
            *(bufp+screen->format->Rshift/8) = R;
            *(bufp+screen->format->Gshift/8) = G;
            *(bufp+screen->format->Bshift/8) = B;
        }
        break;

        case 4: { /* Probably 32-bpp */
            Uint32 *bufp;

            bufp = (Uint32 *)screen->pixels + y*screen->pitch/4 + x;
            *bufp = color;
        }
        break;
    }
    if ( SDL_MUSTLOCK(screen) ) {
        SDL_UnlockSurface(screen);
    }
    SDL_UpdateRect(screen, x, y, 1, 1);
}

int main(int argc, char** argv) {
	// Let's get rolling!
	if(SDL_Init( SDL_INIT_VIDEO | SDL_INIT_TIMER ) == -1) {
		printf("[SDLWabbitemu] SDL init failed, so exiting.\n");
		return 1;
	}
	screen = SDL_SetVideoMode( 320, 240, 32, SDL_SWSURFACE | SDL_RESIZABLE);// | SDL_DOUBLEBUF );
	SDL_WM_SetCaption("SDLWabbitemu", 0);
	SDL_Event event;
	bool emuRunning = true;
	
	// Set up lcdsurface
	/*SDL_PixelFormat* pxlformat;
	int w = 128;
	int h = 64;
	pxlformat=screen->format;
	lcdsurface = SDL_CreateRGBSurface(SDL_SRCALPHA|SDL_SRCCOLORKEY|SDL_SWSURFACE,
			w,
			h,
			pxlformat->BitsPerPixel,
			pxlformat->Rmask,
			pxlformat->Gmask,
			pxlformat->Bmask,
			pxlformat->Amask);*/
	lcdsurface = SDL_DisplayFormat(screen);
	
	// Get emulator core running
	printf("Initializing emulator core...\n");
	if (!(start_main())) {
		printf("[SDLWabbitemu] Emulator core initilization failed, so exiting.\n");
		exit(1);
	}
	
	// Blit lcdsurface!
	SDL_Rect offset; 
	offset.x = 10; 
	offset.y = 10;
	offset.w = 128;
	offset.h = 64;
	
	while (emuRunning) {
		//printf_d("[SDLWabbitemu] Main loop iter\n");
		if (SDL_PollEvent(&event)) {
			if (event.type == SDL_QUIT) {
				printf("[SDLWabbitemu] Got SDL_QUIT, so exiting.\n");
				emuRunning = false;
			}
			if( event.type == SDL_VIDEORESIZE ) { 
				printf_d("[SDLWabbitemu] Detected window resize, sending event to OnResize.\n");
				OnResize(event.resize);
			}
			if (event.type == SDL_KEYDOWN) {
				printf_d("[SDLWabbitemu] Detected key down, sending event to OnKeyDown.\n");
				OnKeyDown(event.key);
			}
			if (event.type == SDL_KEYUP) {
				printf_d("[SDLWabbitemu] Detected key up, sending event to OnKeyUp.\n");
				OnKeyUp(event.key);
			}
		}
		SDL_UnlockSurface(lcdsurface);
		//OnTimer(0, NULL);
		//if (SDL_MUSTLOCK(lcdsurface)) {
		//	printf("[SDLWabbitemu] lcdsurface unlocked!\n");
			//SDL_UnlockSurface(lcdsurface);
		//}
		//SDL_LockSurface(screen);
		//SDL_BlitSurface(lcdsurface, NULL, screen, &offset);
		//SDL_UnlockSurface(screen);
		SDL_BlitSurface(lcdsurface, NULL, screen, &offset);
		SDL_Flip(lcdsurface);
		if( SDL_Flip( screen ) == -1 ) {
			printf("[SDLWabbitemu] Failed to perform SDL_Flip, so exiting.\n");
			return 1;
		}
		
	}
	// Clean up, clean up, everybody do their share...
	//OnQuit();
	//SDL_FreeSurface(lcdsurface);
	//SDL_FreeSurface(screen);
	SDL_Quit();
	return 0;
}
